using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Data;
using System.Windows.Forms;
using System.Net;
using System.Diagnostics;


using Hydrobase;

namespace RSSApplicationUpdater
{
    /// <summary>
    /// This class handles the update the application.
    /// </summary>
    public class ApplicationUpdater:Core 
    { 

        string   feeduri;
        static string  applicationVerForUpd;
        RssFeed updFedd;
        Properties prop = new Properties();
        ProgressDialog progrsdilog;
      public static   WebClient clent ;
        string currentfileDownload;
        /// <summary>
        /// The intialisation of the configuring the class
        /// </summary>
        /// <param name="DoConf">true for excuting the configuration of the class</param>
        public ApplicationUpdater(bool DoConf)
        {
            if (DoConf == true)
            {

                base.GetConfig();
                ReadValues();
                
            }


        }
        /// <summary>
        /// Set or Get the configuration of the library
        /// </summary>
        public Properties properties
        {


            set
            {
                prop = value;


            }
            get
            {
                return prop;

            }
        }
        /// <summary>
        /// Gets the assembly of the executing applicaion and takes the version
        /// </summary>
        /// <param name="app">The assemply of the executing application</param>
        public void  GetExeCutingApplicationVersion(Assembly  app)
        {
            try
            {
                if (app != null)
                {
                    applicationVerForUpd = app.GetName().Version.ToString();
                   // MessageBox.Show(applicationVerForUpd);



                }
                else
                {

                    applicationVerForUpd = Assembly.LoadFile(Application.ExecutablePath).GetName().Version.ToString();


                }
                

            }
            catch (Exception e)
            {

                Core.errorreport(e);
                
            }


        }
     /// <summary>
     /// Reads the values form the already readen configuration
     /// </summary>
        public void ReadValues()
        {
            try
            {
                if ((set.Tables.Count > 0) || (set.Tables[0] != null))
                {
                    DataTable table = set.Tables[0];
                   // DataRow row;
                    object[] vals;
                    vals = table.Rows[0].ItemArray;
                    int i;
                    i = table.Columns.IndexOf(cells[0]);
                    prop.ApplicationName = Convert.ToString(vals[i]);
                    i = table.Columns.IndexOf(cells[1]);
                    prop.URI = Convert.ToString(vals[i]);
                    i = table.Columns.IndexOf(cells[2]);
                    prop.Release_State = Convert.ToString(vals[i]);
                    if (table.Columns.Contains(cells[3]) == true)
                    {
                        i = table.Columns.IndexOf(cells[3]);
                        if (vals[i] != null)
                        {
                            prop.CMS = Convert.ToString(vals[i]);
                        }
                        else
                        {
                            prop.CMS = enumCms.Drupal.ToString();

                        }
                    }
                    if (table.Columns.Contains(cells[4]) == true)
                    {
                        i = table.Columns.IndexOf(cells[4]);

                        prop.AutoCheck = Convert.ToBoolean (vals[i]);


                    }
                    if (table.Columns.Contains(cells[5]) == true)
                    {
                        i = table.Columns.IndexOf(cells[5]);
                        
                            prop.Application_WebSite= Convert.ToString(vals[i]);
                        
                        
                    }
                    if (table.Columns.Contains(cells[6]) == true)
                    {
                        i = table.Columns.IndexOf(cells[6]);

                        prop.Alpha_feed = Convert.ToString(vals[i]);


                    }
                    if (table.Columns.Contains(cells[7]) == true)
                    {
                        i = table.Columns.IndexOf(cells[7]);

                        prop.Beta_feed = Convert.ToString(vals[i]);


                    }
                    if (table.Columns.Contains(cells[8]) == true)
                    {
                        i = table.Columns.IndexOf(cells[8]);

                        prop.RC_feed = Convert.ToString(vals[i]);


                    }
                    if (table.Columns.Contains(cells[9]) == true)
                    {
                        i = table.Columns.IndexOf(cells[9]);

                        prop.Stable_feed = Convert.ToString(vals[i]);


                    }
                    
                    


                }

            }
            catch (Exception e)
            {
                Core.errorreport(e);

            }


        }
        /// <summary>
        /// Parses the rss feed from the given configuration and takes the feed.
        /// </summary>
        public void GetTheFeed()
        {
            try
            {
                

                    if (prop.Release_State.ToLower() == "alpha")
                    {
                        updFedd = RssFeed.FromUri(prop.Alpha_feed);

                        if (updFedd == null)
                        {
                            updFedd = RssFeed.FromUri(prop.URI);

                        }



                    }
                    else if (prop.Release_State.ToLower() == "beta")
                    {

                        updFedd = RssFeed.FromUri(prop.Beta_feed);
                        if (updFedd == null)
                        {
                            updFedd = RssFeed.FromUri(prop.URI);

                        }


                    }
                    else if (prop.Release_State.ToLower() == "rc")
                    {

                        updFedd = RssFeed.FromUri(prop.RC_feed);
                        if (updFedd == null)
                        {
                            updFedd = RssFeed.FromUri(prop.URI);

                        }


                    }
                    else if ((prop.Release_State.ToLower() == "stable") || (prop.Release_State.ToLower()=="final"))
                    {
                       
                        updFedd = RssFeed.FromUri(prop.Stable_feed);

                        if (updFedd == null)
                        {
                            updFedd = RssFeed.FromUri(prop.URI);

                        }

                    }
                    else
                    {
                        if (prop.URI != null)
                        {
                            updFedd = RssFeed.FromUri(prop.URI);
                        }
                    }
                
                
            }
            catch (Exception e)
            {
                Core.errorreport(e);

            }
        }
        /// <summary>
        /// Checks for a a new version and returns the attachment from the
        /// current rss feed.
        /// </summary>
        /// <returns>returns the attachment from the
        /// current rss feed.</returns>
        public string  CheckforNewVersion()
        {
            try
            {
                string  ap = null;
                GetTheFeed();
               
                if (updFedd.MainChannel != null)
                {
                    RssChannel chanel = updFedd.MainChannel;
                    int i, j,z,f;
                   
                    if (prop.CMS ==enumCms.Drupal.ToString())
                    {

                    if ((chanel != null) &&(applicationVerForUpd !=null))
                    {
                        //MessageBox.Show("hi2 " + prop.ApplicationName);
                        foreach (RssItem item in chanel.Items)
                        {
                           // MessageBox.Show("hi4 " + item.Title);
                         //  MessageBox.Show("hi5 " + prop.Release_State);

                           // MessageBox.Show(applicationVerForUpd);
                           z = item.Title.LastIndexOf("[") + 1;
                           f = item.Title.LastIndexOf("]") + 1;
                           if ((item.Title.Contains(prop.Release_State) == true) || (item.Title.Contains(prop.Release_State.ToLower()) == true) || (item.Title.Contains(prop.Release_State.ToUpper()) == true)  )
                            {
                                
                                i = item.Title.LastIndexOf("(")+1;
                                j = item.Title.LastIndexOf(")")+1;
                                //MessageBox.Show("hi3" + item.Title.Substring(i, item.Title.Length - j));
                                string tmp = item.Title.Substring(i, item.Title.Length - j);
                                if ((tmp!=null ) && ((tmp.Contains("(") == true) || (tmp.Contains(")") == true)))
                                {
                                   tmp= tmp.Replace("(", " ");
                                   tmp=tmp.Replace(")", " ");
                                   tmp = tmp.Trim(null);
                                   

                                
                               Version apver = new Version(applicationVerForUpd);
                              // MessageBox.Show(tmp);
                               Version newap = new Version(tmp);
                               
                               // if (apver.CompareTo(newap)>0)
                               if ((newap !=null)&&(newap.CompareTo(apver) > 0) )
                                {

                                    //Version ver = new Version();
                                    


                                   // DownloadFileVersion(item.Enclosure_url);

                                    return item.Enclosure_url;
                                }
                            }


                            }

                        }

                    }
                    }
                    else if (prop.CMS == enumCms.SourceForge.ToString())
                    {
                        if ((chanel != null) && (applicationVerForUpd != null))
                        {
                            //MessageBox.Show("hi2 " + prop.ApplicationName);
                            foreach (RssItem item in chanel.Items)
                            {
                                // MessageBox.Show("hi4 " + item.Title);
                                //  MessageBox.Show("hi5 " + prop.Release_State);

                                // MessageBox.Show(applicationVerForUpd);
                                z = item.Title.LastIndexOf("[") + 1;
                                f = item.Title.LastIndexOf("]") + 1;
                                if ((item.Title.Contains(prop.Release_State) == true) || (item.Title.Contains(prop.Release_State.ToLower()) == true) || (item.Title.Contains(prop.Release_State.ToUpper()) == true))
                                {

                                    i = item.Title.LastIndexOf("{") + 1;
                                    j = item.Title.LastIndexOf("}") + 1;
                                    //MessageBox.Show("hi3" + item.Title.Substring(i, item.Title.Length - j));
                                    string tmp = item.Title.Substring(i, item.Title.Length - j);
                                    if ((tmp != null) && ((tmp.Contains("{") == true) || (tmp.Contains("}") == true)))
                                    {
                                        tmp = tmp.Replace("{", " ");
                                        tmp = tmp.Replace("}", " ");


                                    }
                                    Version apver = new Version(applicationVerForUpd);
                                    // MessageBox.Show(tmp);
                                    Version newap = new Version(tmp);

                                    // if (apver.CompareTo(newap)>0)
                                    if ((newap != null) && (newap.CompareTo(apver) > 0))
                                    {

                                        //Version ver = new Version();



                                        // DownloadFileVersion(item.Enclosure_url);

                                        return item.Link ;
                                    }


                                }

                            }

                        }


                    }


                }

                return ap;


            }
            catch (Exception e)
            {

                Core.errorreport(e);
                return null;
            }


        }
        /// <summary>
        /// Checks for a a new version and returns  the
        /// current rss feed.
        /// </summary>
        /// <returns>returns  the
        /// current rss feed.</returns>
        public void CheckforNewVersionsChangeLog()
        {
            try
            {
                RssItem ap = null ;
                GetTheFeed();
                 
               if (updFedd != null)
               {
                   //MessageBox.Show(prop.CMS);
                    if (updFedd.MainChannel != null)
                    {

                        RssChannel chanel = updFedd.MainChannel;
                        int i, j, z, f;

                        if ((prop.CMS == enumCms.Drupal.ToString() ) ||(prop.CMS !=null))
                        {

                            if ((chanel != null) && (applicationVerForUpd != null))
                            {
                                
                                foreach (RssItem item in chanel.Items)
                                {
                                   
                                    z = item.Title.LastIndexOf("[") + 1;
                                    f = item.Title.LastIndexOf("]") + 1;
                                   
                                    if ((item.Title.Contains(prop.Release_State) == true) 
                                        || (item.Title.Contains(prop.Release_State.ToLower()) == true) 
                                        || (item.Title.Contains(prop.Release_State.ToUpper()) == true))
                                    {
                                        
                                        i = item.Title.LastIndexOf("(") + 1;
                                        j = item.Title.LastIndexOf(")") ;
                                        //MessageBox.Show("hi3" + item.Title.Substring(i, item.Title.Length - j));
                                        string tmp = item.Title.Substring(i, item.Title.Length - j);
                                        if ((tmp != null) || ((tmp.Contains("(") == true) || (tmp.Contains(")") == true) || (tmp.Contains(" ( ") == true) || (tmp.Contains(" ) ") == true) || (tmp.Contains(" (") == true) || (tmp.Contains("( ") == true) || (tmp.Contains(" )") == true) || (tmp.Contains(") ") == true)))
                                        {
                                            tmp = tmp.Replace("(", " ");
                                            tmp = tmp.Replace(")", " ");

                                           // tmp = tmp.TrimStart(null);
                                           tmp = tmp.Trim(null);



                                            Version apver = new Version(applicationVerForUpd);
                                           // MessageBox.Show(tmp);
                                           Version newap = new Version(tmp);

                                            // if (apver.CompareTo(newap)>0)
                                           // MessageBox.Show(newap.ToString());
                                           if ((newap != null) && (newap.CompareTo(apver) > 0))
                                            {

                                                //Version ver = new Version();



                                                // DownloadFileVersion(item.Enclosure_url);

                                                ap = item;
                                                break;

                                            }


                                        }


                                    }

                                }
                                if (ap != null)
                                {
                                    clent = new WebClient();
                                    WebBrowser webbowser = new WebBrowser(ap);

                                    webbowser.Article_RSS = ap;
                                    webbowser.Show();
                                }

                            }

                        }
                        else if (prop.CMS == enumCms.SourceForge.ToString())
                        {
                          
                           if ((chanel != null) || (applicationVerForUpd != null))
                            {
                             //MessageBox.Show("hi2 " + prop.ApplicationName);
                                foreach (RssItem item in chanel.Items)
                                {
                                    // MessageBox.Show("hi4 " + item.Title);
                                    //  MessageBox.Show("hi5 " + prop.Release_State);

                                   // MessageBox.Show(applicationVerForUpd);
                                    z = item.Title.LastIndexOf("[") + 1;
                                    f = item.Title.LastIndexOf("]") + 1;
                                    if ((item.Title.Contains(prop.Release_State) == true)
                                        || (item.Title.Contains(prop.Release_State.ToLower()) == true) 
                                        || (item.Title.Contains(prop.Release_State.ToUpper()) == true))
                                    {

                                        i = item.Title.LastIndexOf("{") + 1;
                                        j = item.Title.LastIndexOf("}") + 1;
                                        //MessageBox.Show("hi3" + item.Title.Substring(i, item.Title.Length - j));
                                        string tmp = item.Title.Substring(i, item.Title.Length - j);
                                        if ((tmp != null) ||((tmp.Contains("{") == true) || (tmp.Contains("}") == true)))
                                        {
                                            tmp = tmp.Replace("{", " ");
                                            tmp = tmp.Replace("}", " ");
                                            tmp = tmp.Trim(null);


                                        }
                                        Version apver = new Version(applicationVerForUpd);
                                        // MessageBox.Show(tmp);
                                        Version newap = new Version(tmp);

                                        // if (apver.CompareTo(newap)>0)
                                      
                                        if ((newap != null) || (newap.CompareTo(apver) > 0))
                                        {

                                            //Version ver = new Version();



                                            // DownloadFileVersion(item.Enclosure_url);

                                            ap = item;
                                            break;
                                        }

                                    }

                                }
                               if (ap != null)
                                {
                                    WebBrowser webbowser = new WebBrowser(ap);

                                    webbowser.Article_RSS = ap;
                                    webbowser.Show();
                                }


                            }


                        }
                        else if (prop.CMS == enumCms.codeplex.ToString())
                        {

                            if ((chanel != null) || (applicationVerForUpd != null))
                            {
                                //MessageBox.Show("hi2 " + prop.ApplicationName);
                                foreach (RssItem item in chanel.Items)
                                {
                                    // MessageBox.Show("hi4 " + item.Title);
                                    //  MessageBox.Show("hi5 " + prop.Release_State);

                                    // MessageBox.Show(applicationVerForUpd);
                                    
                                    z = item.Title.LastIndexOf("[") + 1;
                                    f = item.Title.LastIndexOf("]") + 1;
                                   if ((item.Title.Contains(prop.Release_State) == true)
                                        || (item.Title.Contains(prop.Release_State.ToLower()) == true)
                                        || (item.Title.Contains(prop.Release_State.ToUpper()) == true)) 
                                    {

                                        i = item.Title.LastIndexOf("{") + 1;
                                        j = item.Title.LastIndexOf("}") + 1;
                                      //MessageBox.Show("hi3" + item.Title.Substring(i, item.Title.Length - j));
                                        string tmp = item.Title.Substring(i, item.Title.Length - j);
                                        if ((tmp != null) || ((tmp.Contains("{") == true) || (tmp.Contains("}") == true)))
                                        {
                                            tmp = tmp.Replace("{", " ");
                                            tmp = tmp.Replace("}", " ");
                                            tmp = tmp.Trim(null);


                                        }
                                        Version apver = new Version(applicationVerForUpd);
                                        // MessageBox.Show(tmp);
                                        Version newap = new Version(tmp);

                                        // if (apver.CompareTo(newap)>0)

                                        if ((newap != null) || (newap.CompareTo(apver) > 0))
                                        {

                                            //Version ver = new Version();



                                            // DownloadFileVersion(item.Enclosure_url);

                                            ap = item;
                                            break;
                                        }

                                    }

                                }
                                if (ap != null)
                                {
                                    WebBrowser webbowser = new WebBrowser(ap);

                                    webbowser.Article_RSS = ap;
                                    webbowser.Show();
                                }


                            }


                        }



                    }
                }

                


            }
            catch (Exception e)
            {

                Core.errorreport(e);
                
            }


        }
        /// <summary>
        /// Downloads the New version of the file.
        /// </summary>
        public void DownloadNewVersion()
        {
            try
            {
                //MessageBox.Show(prop.CMS + "\n" + updFedd.MainChannel);
                string url =CheckforNewVersion();
                string tfilename;

                if (url != null)
                {
                    tfilename = Path.GetFileName(url);

                    if (Directory.Exists(Application.StartupPath + "\\" + updatesfolder) == false)
                    {
                        Directory.CreateDirectory(Application.StartupPath + "\\" + updatesfolder);

                    }
                    if (tfilename != null)
                    {
                        if (File.Exists(Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename) == true)
                        {
                            File.Delete(Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename);

                        }
                        Uri url2 = new Uri(url);
                        clent = new WebClient();
                        progrsdilog = new ProgressDialog();
                        progrsdilog.Text = "RSS File Application Updater";
                        progrsdilog.Show();
                        clent.DownloadFileAsync(url2, Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename);
                        clent.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Webclient_Progresschanged);
                        clent.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(this.Webclient_FileCompleted);
                        currentfileDownload = Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename;
                    }
                }
                else
                {
                    MessageBox.Show("No Update is available");

                }

            }
            catch (Exception e)
            {

                Core.errorreport(e);
            }



        }

        public void DownloadNewVersionFromFeed(string Feedurl)
        {
            try
            {
                //MessageBox.Show(prop.CMS + "\n" + updFedd.MainChannel);
               // string url = CheckforNewVersion();
                string tfilename;

                if (Feedurl != null)
                {
                    tfilename = Path.GetFileName(Feedurl);

                    if (Directory.Exists(Application.StartupPath + "\\" + updatesfolder) == false)
                    {
                        Directory.CreateDirectory(Application.StartupPath + "\\" + updatesfolder);

                    }
                    if (tfilename != null)
                    {
                        if (File.Exists(Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename) == true)
                        {
                            File.Delete(Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename);

                        }
                        Uri url2 = new Uri(Feedurl);
                        clent = new WebClient();
                        progrsdilog = new ProgressDialog();
                        progrsdilog.Text = "RSS File Application Updater";
                        progrsdilog.Show();
                        //clent = new WebClient();
                        clent.DownloadFileAsync(url2, Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename);
                        clent.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Webclient_Progresschanged);
                        clent.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(this.Webclient_FileCompleted);
                        currentfileDownload = Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename;
                    }
                }
                else
                {
                    MessageBox.Show("No Update is available");

                }

            }
            catch (Exception e)
            {

                Core.errorreport(e);
            }



        }
        /// <summary>
        /// Downloads the New version of the file.
        /// 
        /// </summary>
        public void DownloadNewVersion2()
        {
            try
            {
                
                        progrsdilog = new ProgressDialog(true);
                        progrsdilog.Show();
                       
                    
               

            }
            catch (Exception e)
            {

                Core.errorreport(e);
            }



        }
        /// <summary>
        /// Downlaods the given file .
        /// If it exists already it deletes it.
        /// </summary>
        /// <param name="url">the url of  the file that you want to download</param>
        public void DownloadFileVersion(string url)
        {
            try
            {
                //string url = CheckforNewVersion();
                string tfilename;
                WebClient clent = new WebClient();
                if (url != null)
                {
                    tfilename = Path.GetFileName(url);

                    if (Directory.Exists(Application.StartupPath + "\\" + updatesfolder) == false)
                    {
                        Directory.CreateDirectory(Application.StartupPath + "\\" + updatesfolder);

                    }
                    if (tfilename != null)
                    {
                        Uri url2 = new Uri(url);
                        clent = new WebClient();
                        clent.DownloadFileAsync(url2, Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename);
                       
                        progrsdilog.Text = "RSS  Application Updater";
                        progrsdilog.Show();
                        
                        clent.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Webclient_Progresschanged);
                        clent.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(this.Webclient_FileCompleted);
                        currentfileDownload = Application.StartupPath + "\\" + updatesfolder + "\\" + tfilename;
                        
                    }
                }

            }
            catch (Exception e)
            {

                Core.errorreport(e);
            }



        }
        private void Webclient_Progresschanged(object sender,DownloadProgressChangedEventArgs ev)
        {
            try
            {
                progrsdilog.Text = "RSS  Application Updater : " + ev.ProgressPercentage + " %";
                progrsdilog.progressBar.Value = ev.ProgressPercentage ;
              //  progrsdilog.Refresh();
                
            }

            catch (Exception e)
            {

                Core.errorreport(e);
            }
        }
        private void Webclient_FileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs ev)
        {
            try
            {
                progrsdilog.Close();
                if ((currentfileDownload != null) || (File.Exists(currentfileDownload) == true))
                {
                    
                    Process.Start(currentfileDownload) ;
                    MessageBox.Show("Download Completed \nNow The Application will close and the update will be installed.");
                    System.Windows.Forms.Application.Exit();
                }
              
                
                    
                
            }

            catch (Exception e)
            {

                Core.errorreport(e);
            }

        }
        public void SaveConfig()
        {
            try
            {
                if ((prop != null) &&(Core.set!=null ) &&(Core.set.Tables[0]!=null))
                {

                    object[] vals = Core.set.Tables[0].Rows[0].ItemArray;
                    vals[0] = prop.ApplicationName;
                    vals[1] = prop.URI;
                    vals[2] = prop.Release_State;
                  //  if (vals.Length >= 4)
                    //{
                        vals[3] = prop.CMS;


                    
                  //  }
                   // else if (vals.Length >= 5)
                    //{

                        vals[4] = Convert.ToString(prop.AutoCheck);

                   // }

                  //  else if (vals.Length >= 6)
                   // {
                        vals[5] = prop.Application_WebSite;
                        vals[6] = prop.Alpha_feed;
                        vals[7] = prop.Beta_feed;
                        vals[8] = prop.RC_feed;
                        vals[9] = prop.Stable_feed;

                   // }
                    
                    Core.set.Tables[0].Rows[0].ItemArray = vals;
                if (File.Exists(Application.StartupPath + "\\" + configfile)== true)
                {

                    Core.ado.SaveTable(Core.set, Application.StartupPath + "\\" + configfile, 0, Application.ProductName + " - " + Application.ProductVersion);

                  

                }

                }


            }

            catch (Exception e)
            {

                Core.errorreport(e);
            }

        }
        /// <summary>
        /// Returns the collection of feed that has a  release
        /// </summary>
        /// <returns>Returns the collection of feed that has a  release</returns>

       /* public RssFeedCollection GetFeedRleasesColction()
        {

            try
            {
                RssFeedCollection ap = null;

                if ((prop.Feed_List_File != null) &&(File.Exists(prop.Feed_List_File)==true))
                {
                    ap = new RssFeedCollection();

                    StreamReader reader = new StreamReader(prop.Feed_List_File);
                    string tmp;
                    while ((tmp = reader.ReadLine()) != null)
                    {

                        ap.Add(tmp.Substring(0, tmp.IndexOf("#") - 1), tmp.Substring(tmp.IndexOf("#") + 1));
                    }
                   


                }


                return ap;


            }
            catch (Exception e)
            {

                Core.errorreport(e);
                return null;
            }


        }
        */
        
        
    }
}
